﻿// Modificado por Sergio. 02/06/10. Cambiadas las cosas relativas a la vida para que lo maneje la clase Life
// Modificado por Sergio. 15/06/10. Clase simplificada con el agregado de Transform (no estan mas pos,rot y demas)
// Modificado por Laura. 05/07/10. Saque las balas y las puse en la calse weapon y agregue que pueda cambiar de armas.

#region Using Statements

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

using System.IO;
using System.Xml.Serialization;
using Engine;

#endregion

namespace Game
{
    #region S&L
    [Serializable]
    public class PlayerData
    {
        public Vector3 mPrevPosition;
        public Vector3 mPosition;
        public Vector3 mEulerAngles;
        public Vector3 mScale;

        public PlayerIndex mPlayerIndex;

        public int mHealthPoints;
        public int mPrevHealthPoints;
        public bool isAlive;

        public int mSpeed;

        public int mActiveWeapon;

        public List<int> mWeapons;
        public Player CreatePlayerFromData(Player player)
        {
            player.Transform.LastPosition = mPrevPosition;
            player.Transform.Position = mPosition;
            player.Transform.EulerAngles = mEulerAngles;
            player.Transform.Scale = mScale;

            player.Index = mPlayerIndex;

            player.Life.HealthPoints = mHealthPoints;
            player.Life.PrevHealthPoints = mPrevHealthPoints;
            player.Life.IsAlive = isAlive;

            player.Speed = mSpeed;

            player.ActiveWeapon = player.Weapons[mActiveWeapon];

            for (byte e = 0; e < player.Weapons.Count; e++)
                player.Weapons[e].BulletsLeft = mWeapons[e];

            return player;
        }
        public void CreateDataFromPlayer(Player player)
        {
            mPrevPosition = player.Transform.LastPosition;
            mPosition = player.Transform.Position;
            mEulerAngles = player.Transform.EulerAngles;
            mScale = player.Transform.Scale;

            mPlayerIndex = player.Index;

            mHealthPoints = player.Life.HealthPoints;
            mPrevHealthPoints = player.Life.PrevHealthPoints;
            isAlive = player.Life.IsAlive;

            mSpeed = player.Speed;

            mActiveWeapon = player.Weapons.IndexOf(player.ActiveWeapon);

            mWeapons = new List<int>();

            for (byte e = 0; e < player.Weapons.Count; e++)
                mWeapons.Add(player.Weapons[e].BulletsLeft);
        }
    }
    public static class PlayerManager
    {
        public static PlayerData data = new PlayerData();

        public static void SaveFile(string filename, Player player)
        {
            data.CreateDataFromPlayer(player);

            string fullpath = Path.Combine(StorageContainer.TitleLocation, filename);
            FileStream stream = File.Open(fullpath, FileMode.Create);
            try
            {
                XmlSerializer serializer = new XmlSerializer(typeof(PlayerData));
                serializer.Serialize(stream, data);
            }
            finally
            {
                stream.Close();
            }
        }
        public static Player LoadFile(string filename, Player player)
        {
            string fullpath = Path.Combine(StorageContainer.TitleLocation, filename);
            FileStream stream = File.Open(fullpath, FileMode.OpenOrCreate, FileAccess.Read);
            try
            {
                XmlSerializer serializer = new XmlSerializer(typeof(PlayerData));
                data = (PlayerData)serializer.Deserialize(stream);

                return data.CreatePlayerFromData(player);
            }
            catch { }
            finally
            {
                stream.Close();
            }

            return null;
        }
    }
    #endregion
    public class Player
    {
        Transform mTransform;
        PlayerIndex mPlayerIndex;
        PlayerIndex mAuxIndex; //Para devolverle lo que den las funciones
        Life mLife;
        int mSpeed;
        int mActiveWeaponIndex;
        Weapon mActiveWeapon; 
        List<Weapon> mWeapons;
                
        public Player(PlayerIndex index)
        {
            mTransform = new Transform();
            mTransform.Position = new Vector3(0,200,500);
            mTransform.EulerAngles = Vector3.Zero;
            mLife = new Life(100);

            mPlayerIndex = index;

            mSpeed = 10;

            mWeapons = new List<Weapon>();
            mWeapons.Add(new Pistol());
            mWeapons.Add(new Mp5());
            mWeapons.Add(new Type95());

            mActiveWeapon = mWeapons[0];
            mWeapons[0].IsActiveWeapon = true;
            mActiveWeaponIndex = 0;
        }


        public void HandleInput()
        {
            if (mLife.IsAlive)
            {

                mTransform.LastPosition = mTransform.Position;

                if (Input.isKeyPressed(Keys.W) ||
                   Input.isButtonPressed(Buttons.LeftThumbstickUp, mPlayerIndex, out mPlayerIndex))
                    this.MoveForwardRelToCam();
                if (Keyboard.GetState().IsKeyDown(Keys.S) ||
                    Input.isButtonPressed(Buttons.LeftThumbstickDown, mPlayerIndex, out mPlayerIndex))
                    MoveBackwardsRelToCam();
                if (Keyboard.GetState().IsKeyDown(Keys.D) ||
                    Input.isButtonPressed(Buttons.LeftThumbstickRight, mPlayerIndex, out mPlayerIndex))
                    MoveRightRelToCam();
                if (Keyboard.GetState().IsKeyDown(Keys.A) ||
                    Input.isButtonPressed(Buttons.LeftThumbstickLeft, mPlayerIndex, out mPlayerIndex))
                    MoveLeftRelToCam();

                Vector2 r = Input.GetGamePad((int)mPlayerIndex).ThumbSticks.Right;

                if (r.X == 0 && r.Y == 0)
                    mTransform.LookAt(mTransform.Position + mTransform.Forward);
                else
                    mTransform.LookAt(mTransform.Position + new Vector3(r.X, 0, -r.Y));

                if (Input.isKeyPressed(Keys.Up))
                    mTransform.LookAt(mTransform.Position + Vector3.Cross(Camera.ActiveCamera.Transform.Left, Vector3.Up));
                if (Input.isKeyPressed(Keys.Down))
                    mTransform.LookAt(mTransform.Position + Vector3.Cross(Camera.ActiveCamera.Transform.Right, Vector3.Up));
                if (Input.isKeyPressed(Keys.Right))
                    mTransform.LookAt(mTransform.Position + Camera.ActiveCamera.Transform.Right);
                if (Input.isKeyPressed(Keys.Left))
                    mTransform.LookAt(mTransform.Position + Camera.ActiveCamera.Transform.Left);

                if (Input.newLeftClick() || Input.IsNewButtonPress(Buttons.RightTrigger, mPlayerIndex, out mPlayerIndex))
                {
                    mActiveWeapon.Shoot(mTransform.WorldMatrix, mTransform.Position, mTransform.Forward);
                }

            }
        }

        public void Update(GameTime gameTime, Transform cameraTransform)
        {
            mActiveWeapon.Update(gameTime);
        }

        public void MoveForwardRelToCam() { mTransform.Translate(Vector3.Cross(Camera.ActiveCamera.Transform.Left, Vector3.Up) * mSpeed); }
        public void MoveBackwardsRelToCam() { mTransform.Translate(Vector3.Cross(Camera.ActiveCamera.Transform.Right, Vector3.Up) * mSpeed); }
        public void MoveRightRelToCam() { mTransform.Translate(Camera.ActiveCamera.Transform.Right * mSpeed); }
        public void MoveLeftRelToCam() { mTransform.Translate(Camera.ActiveCamera.Transform.Left * mSpeed); }

        public void MoveForward() { mTransform.Position -= new Vector3(0, 0, mSpeed); }
        public void MoveBackwards() { mTransform.Position += new Vector3(0, 0, mSpeed); }
        public void MoveRight() { mTransform.Position += new Vector3(mSpeed, 0, 0); }
        public void MoveLeft() { mTransform.Position -= new Vector3(mSpeed, 0, 0); }

        public void MoveBackwardsRelToMe() { mTransform.Position -= mTransform.Forward * mSpeed; }
        public void MoveForwardRelToMe() { mTransform.Position += mTransform.Forward * mSpeed; }
        public void MoveLeftRelToMe() { mTransform.Position -= mTransform.Right * mSpeed; }
        public void MoveRightRelToMe() { mTransform.Position += mTransform.Right * mSpeed; }

        
        public void Draw(Matrix view, Matrix projection)
        {
            ModelDrawer.Draw("Player", mTransform.WorldMatrix, view, projection);

            mActiveWeapon.Draw(mTransform.WorldMatrix, view, projection);

            //ModelDrawer.Draw("laser", world, view, projection);
        }

        #region Setters & Getters

        public Transform Transform
        {
            get { return this.mTransform; }
            set { this.mTransform = value; }
        }

        public Life Life
        {
            get { return this.mLife; }
            set { this.mLife = value; }
        }

        public int Speed
        {
            get { return this.mSpeed; }
            set { this.mSpeed = value; }
        }

        public PlayerIndex Index
        {
            get { return mPlayerIndex; }
            set { this.mPlayerIndex = value; }
        }

        public List<Weapon> Weapons
        {
            get { return mWeapons; }
            set { this.mWeapons = value; }
        }
        public Weapon ActiveWeapon
        {
            get { return mActiveWeapon; }
            set { mActiveWeapon = value; }
        }
        public int WeaponIndex
        {
            get { return mActiveWeaponIndex; }
        }
        #endregion

    }
}
